/* IMF_CPIS.do (STATA)
	Construct IMF CPIS data.
	by Ralph Koijen & Motohiro Yogo */

#delimit ;
clear all;
set more off;
set type double;

cap log close;
log using IMF_CPIS, replace;

/* Define local and global variables */

local directory = "../../Data/IMF/CPIS";

do global;


/* Step 1: Prepare countries */

u Counterpart Country_Code using Countries, clear;

/* Rename variables */

rename Country_Code Counterpart_Country_Code;

/* Save data */

tempfile Countries;
save `Countries';


/* Step 2: Construct IMF CPIS bilateral positions */

/* Load data */

u Country_Code Indicator_Code Counterpart_Country_Code Counterpart_Sector_Code Sector_Code Attribute
	_$year_min-_$year_max
	if Country_Code!=Counterpart_Country_Code
	& regexm(Indicator_Code,"^I_A_(D_L|D_S|E_T)_T")
	& !inlist(Counterpart_Country_Code,1,31)	/* 1 = World, 31 = World Minus 25 Significant Financial Centers */
	& Counterpart_Sector_Code=="T"
	& Sector_Code=="T"
	using "`directory'/CPIS_03-10-2022", clear;

drop Counterpart_Sector_Code Sector_Code;

/* Code confidential holdings */

sort Country_Code Indicator_Code Counterpart_Country_Code Attribute;

foreach var of varlist _2011 _2012 _2014-_2019 {;
	by Country_Code Indicator_Code Counterpart_Country_Code: replace `var' = ".c" if `var'[_n-1]=="C";
};

drop if Attribute=="Status";

destring _*, replace;

drop Attribute;

/* Reshape in long format */

reshape long _, i(Country_Code Indicator_Code Counterpart_Country_Code) j(year);

/* Rename variables */

rename _ amount;

/* Drop missing data */

drop if missing(amount);

/* Merge investor country code */

replace Country_Code = 354 if Country_Code==355;	/* Curacao and Sint Maarten -> Curacao */

merge m:1 Country_Code using Countries,
	keepusing(country Iofc)
	nogen keep(master match);

replace country = "_CR" if Country_Code==93;	/* 93 = International Organizations and SEFER */
replace Iofc = 0 if Country_Code==93;

drop Country_Code;

/* Merge issuer country code */

merge m:1 Counterpart_Country_Code using `Countries',
	nogen keep(master match);

replace Counterpart = "_OC" if inlist(Counterpart_Country_Code,91,983);	/* 91 = International Organizations, 983 = Not Specified */

drop Counterpart_Country_Code;

/* Reassign territories to countries */

foreach var of varlist country Counterpart {;
	replace `var' = "GBR" if `var'=="GIB";	/* Gibraltar -> UK */
	replace `var' = "SRB" if `var'=="XKX";	/* Kosovo -> Serbia */
	replace `var' = "NLD" if `var'=="CUW";	/* Curacao -> Netherlands */
};

drop if country==Counterpart;

/* Construct variables */

gen byte type = 1 if regexm(Indicator_Code,"^I_A_D_S");
replace type = 2 if regexm(Indicator_Code,"^I_A_D_L");
replace type = 3 if regexm(Indicator_Code,"^I_A_E_T");

drop Indicator_Code;

/* Aggregate across territories and other countries */

collapse (sum) amount, by(year country Counterpart type Iofc) fast;

/* Convert to US$ billion and truncate short positions */

replace amount = max(amount/1e9,0);
/*
/* Replace amounts below reportable threshold */

gen Lamount1 = ln(amount);
gen Lamount2 = ln(amount);
replace Lamount2 = ln($small) if amount==0;

qui forval y = $year_min/$year_max {;
	forval j = 1/3 {;
		xi: intreg Lamount1 Lamount2 i.country i.Counterpart if year==`y' & type==`j', robust;

		predict ystar if year==`y' & type==`j', ystar(Lamount1,Lamount2);

		replace amount = exp(ystar) if year==`y' & type==`j' & amount==0;

		drop ystar;
	};
};

xi;

drop Lamount*;
*/
/* Merge share in common equity */

merge m:1 year country Counterpart type using Restatement_equity,
	keep(master match);

/* Assume common equity if breakdown unknown */

replace Scommon = 1 if type==3 & _merge==1;

/* Split into common equity and fund shares */

expand 2 if _merge==3, gen(duplicate);

replace type = type+duplicate;

replace amount = amount*Scommon if type==3;		/* Common equity */
replace amount = amount*(1-Scommon) if type==4;	/* Fund shares */

drop Scommon _merge duplicate;

/* Drop zeros */

drop if amount==0;

/* Label variables */

order year country Counterpart type Iofc;

label var year		"Year";
label var type		"Asset type";

label var amount	"Investment amount (US$ billion)";

label define type_label
	1 "Short-term debt"
	2 "Long-term debt"
	3 "Equity"
	4 "Fund shares", replace;

label val type type_label;

/* Save data */

sort year country Counterpart type;

save IMF_CPIS, replace;


/* Step 3: Construct IMF CPIS currency composition */

/* Load data */

u Country_Code Indicator_Code Attribute
	_$year_min-_$year_max
	if regexm(Indicator_Code,"^I_A_(D_L|D_S|E_T)_(USD|CHF|EUR|GBP|JPY|USD)")
	& Attribute=="Value"
	using "`directory'/CPIS_03-10-2022", clear;

drop Attribute;

/* Fix variables */

destring _*, replace;

/* Reshape in long format */

reshape long _, i(Country_Code Indicator_Code) j(year);

/* Rename variables */

rename _ Tcurrency;

/* Drop missing data */

drop if missing(Tcurrency);

/* Merge country code */

merge m:1 Country_Code using Countries,
	keepusing(country)
	nogen keep(master match);

drop Country_Code;

/* Reassign territories to countries */

replace country = "GBR" if country=="GIB";	/* Gibraltar -> UK */
replace country = "SRB" if country=="XKX";	/* Kosovo -> Serbia */
replace country = "NLD" if country=="CUW";	/* Curacao -> Netherlands */

/* Construct variables */

gen byte type = 1 if regexm(Indicator_Code,"^I_A_D_S");
replace type = 2 if regexm(Indicator_Code,"^I_A_D_L");
replace type = 3 if regexm(Indicator_Code,"^I_A_E_T");

gen currency = regexs(2) if regexm(Indicator_Code,"^I_A_(D_L|D_S|E_T)_(CHF|EUR|GBP|JPY|USD)");
replace currency = "CHE" if currency=="CHF";
replace currency = "GBR" if currency=="GBP";
replace currency = "JPN" if currency=="JPY";
replace currency = "USA" if currency=="USD";

drop Indicator_Code;

/* Aggregate across territories */

collapse (sum) Tcurrency, by(year country type currency) fast;

/* Convert to US$ billion and truncate short positions */

replace Tcurrency = max(Tcurrency/1e9,0);

/* Drop zeros */

drop if Tcurrency==0;

/* Label variables */

order year country type currency;

label var year		"Year";
label var type		"Asset type";
label var currency	"Currency";

label var Tcurrency	"Investment amount (US$ billion)";

label define type_label
	1 "Short-term debt"
	2 "Long-term debt"
	3 "Equity"
	4 "Fund shares";

label val type type_label;

/* Save data */

sort year country type currency;

save IMF_CPIS_currency, replace;

log close;
